import javax.swing.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Font;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.awt.*;
import java.net.Socket;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Scanner;


public class ReversiWindow extends JFrame implements ActionListener, MouseListener, KeyListener{
	/**
	 * @wbp.nonvisual location=474,91
	 */
	 public Timer timer;
	public JOptionPane serverPortDiff;
	public Socket socket;
	public JPanel dialoguePanel;
	public char[][]positions;
	//All public parts of the GUI
	public JTextPane serverMessagePane;
	public JTextPane commentPane;
	public JTextField serverField, portField;
	//State of various buttons and text fields
	//Difficulty is H, E, M, D (human, easy, medium, hard)
	char localDifficulty;
	String serverDifficulty;
	String server, port, comment;
	int xCoord, yCoord;
	public BufferedReader in;
    public PrintWriter out;
	public boolean valid;
	
	public ReversiWindow(){

/*	timer = new Timer(10, new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
		repaint();
	}    
	});
*/	
		valid = false;
		server = "";
		port = "";
		comment = "";
		localDifficulty = 'H';
		serverDifficulty = "EASY";
		setResizable(false);
		setSize(new Dimension(432, 556));
		setTitle("Reversi");
		getContentPane().setBackground(Color.WHITE);
		setFont(new Font("Lucida Sans", Font.PLAIN, 12));
		setBackground(Color.WHITE);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		getContentPane().setLayout(null);
		
		JPanel panel_1 = new JPanel();
		panel_1.setLayout(null);
		panel_1.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Server Output", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel_1.setBounds(0, 472, 432, 40);
		getContentPane().add(panel_1);
		
		serverMessagePane = new JTextPane();
		serverMessagePane.setBounds(6, 18, 420, 16);
		panel_1.add(serverMessagePane);
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "Comments Box", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.setBounds(0, 432, 432, 40);
		getContentPane().add(panel);
		panel.setLayout(null);
		
		commentPane = new JTextPane();
		commentPane.setBounds(6, 18, 420, 16);
		commentPane.addKeyListener(this);
		panel.add(commentPane);
		
		JMenuBar menuBar = new JMenuBar();
		JMenu gameMenu = new JMenu("Game");
		gameMenu.setMnemonic(KeyEvent.VK_G);
		gameMenu.getAccessibleContext().setAccessibleDescription(
		        "Access Game Options");
		menuBar.add(gameMenu);
		
		JMenuItem newGame = new JMenuItem("New Game");
		newGame.setMnemonic(KeyEvent.VK_N);
		newGame.setActionCommand("New Game");
		newGame.addActionListener(this);
		gameMenu.add(newGame);
		

		
		setJMenuBar(menuBar);
		
		JMenu mnEdit = new JMenu("Edit");
		mnEdit.setMnemonic(KeyEvent.VK_E);
		menuBar.add(mnEdit);
		
		JMenuItem mntmUndo = new JMenuItem("Undo");
		mntmUndo.setAccelerator(KeyStroke.getKeyStroke(
		        KeyEvent.VK_1, ActionEvent.ALT_MASK));
		mntmUndo.addActionListener(this);
		mnEdit.add(mntmUndo);
		//This code is all for the dialogue box
		//That pops up for choosing difficult and server/port options
		serverPortDiff = new JOptionPane();
		dialoguePanel = new JPanel(new GridLayout(0,1));
		//Specifies all the radio buttons needed for difficulty

		JRadioButton humanButton = new JRadioButton("Human");
		humanButton.setActionCommand("Human");
		humanButton.addActionListener(this);
		JRadioButton easyButton = new JRadioButton("Easy");
		easyButton.setActionCommand("Easy");
		easyButton.addActionListener(this);
		JRadioButton medButton = new JRadioButton("Medium");
		medButton.setActionCommand("Medium");
		medButton.addActionListener(this);
		JRadioButton hardButton = new JRadioButton("Hard");
		hardButton.setActionCommand("Hard");
		hardButton.addActionListener(this);
		JRadioButton easyButton2 = new JRadioButton("Easy");
		easyButton2.setActionCommand("Easy2");
		easyButton2.addActionListener(this);
		JRadioButton medButton2 = new JRadioButton("Medium");
		medButton2.setActionCommand("Medium2");
		medButton2.addActionListener(this);
		JRadioButton hardButton2 = new JRadioButton("Hard");
		hardButton2.setActionCommand("Hard2");
		hardButton.addActionListener(this);
		ButtonGroup diffGroup = new ButtonGroup();
		ButtonGroup diffGroup2 = new ButtonGroup();
		diffGroup.add(humanButton);
		diffGroup.add(easyButton);
		diffGroup.add(medButton);
		diffGroup.add(hardButton);
		humanButton.setSelected(true);
		diffGroup2.add(easyButton2);
		diffGroup2.add(medButton2);
		diffGroup2.add(hardButton2);
		
		JLabel serverLabel = new JLabel("Server: ");
		JLabel portLabel = new JLabel("Port: ");
		JLabel localDiff = new JLabel("Local Difficulty: ");
		JLabel otherDiff = new JLabel("Server Difficulty: ");
		serverField = new JTextField(20);
//		portField = new JTextField(20);
		dialoguePanel.add(localDiff);
		dialoguePanel.add(humanButton);
		dialoguePanel.add(easyButton);
		dialoguePanel.add(medButton);
		dialoguePanel.add(hardButton);
		dialoguePanel.add(otherDiff);
		dialoguePanel.add(easyButton2);
		dialoguePanel.add(medButton2);

		dialoguePanel.add(hardButton2);
		dialoguePanel.add(serverLabel);
		dialoguePanel.add(serverField);
//		dialoguePanel.add(portLabel);
//		dialoguePanel.add(portField);
	
		addMouseListener(this);

		positions = new char[8][8]; 
		for(int i=0; i<64; i++){
             positions[i/8][i%8] = 'O';
		 }
		
	}
	
	
	public void paint(Graphics g){
		super.paint(g);
		
		g.setColor(Color.black);
		
		//Setup grid
		for (int i = 0; i <= 8; i++){
			g.drawLine(0,(i*54)+44,432,(i*54)+44);
			g.drawLine(i*54, 0+44, i*54, 476);
			
		}
		if(valid == false) return;
		//Draw all reversi tiles
		//Need a way to get board state over here
		
		for (int j = 0; j < 8; j++){
			for (int i = 0; i < 8; i++){
				if (positions[i][j] == 'W'){
					g.setColor(Color.blue);
					g.fillOval((i*54)+2, (j*54)+44+2, 50, 50);
				}else if(positions[i][j] == 'B'){
					g.setColor(Color.black);
					g.fillOval((i*54)+2, (j*54)+44+2, 50, 50);
				}
			}
		}
	}
	public static void main(String[] args){
		  SwingUtilities.invokeLater(new Runnable() {
	            @Override
	            public void run() {
	                ReversiWindow rWindow = new ReversiWindow();
	               
	                rWindow.setVisible(true);
	            }
	        });
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		//Menu Option for new game
		if (e.getActionCommand() == "New Game"){
			try{
				if(valid){
					out.println("EXIT");
					try{
						socket.close();
					} catch (IOException z) {
					//Can't close Socket first time...
					}
				}
			commentPane.setText("");		
			serverPortDiff.showMessageDialog(this, dialoguePanel, "Options", JOptionPane.PLAIN_MESSAGE);
			server = serverField.getText();
//			port = portField.getText();
			socket = new Socket( server, 9898);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
			String s;
			s = in.readLine();
			out.println("OINK");  //Throwaway line the server needs to 'eat'
			valid = true;
			out.println("BLACK");
			out.println(serverDifficulty);
			out.println("DISPLAY");
			updateState();
			repaint();
//			timer.start();
			}catch( UnknownHostException f){
				commentPane.setText("Unknown HostName.  Please try again!");
			}catch(IOException f){
				commentPane.setText("Error creating IO streams.  No new game created.  Please try again.");
			}
		}
		//Menu Option Undo
		else if(e.getActionCommand()=="Undo"){
			out.println("UNDO");
			String s = "";
			try{
			s = in.readLine();
			}catch(IOException z){
			}
			parseComments(s);
//			serverMessagePane.setText("Undo");
			updateState();
			repaint();
			
		}
		else if(e.getActionCommand()=="Human"){
			localDifficulty = 'H';
		}
		else if(e.getActionCommand()=="Medium"){
			localDifficulty = 'M';
		}
		else if(e.getActionCommand()=="Hard"){
			localDifficulty = 'D';
		}
		else if(e.getActionCommand()=="Easy2"){
			serverDifficulty = "EASY";
//			out.println("EASY");
		}
		else if(e.getActionCommand()=="Medium2"){
			serverDifficulty = "MEDIUM";
//			out.println("MEDIUM");
		}
		else if(e.getActionCommand()=="Hard2"){
			serverDifficulty = "HARD";
//			out.println("HARD");
		}else if(e.getActionCommand() == "Comment"){
			
		}
		
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		int x, y;
		x = e.getX();
		y = e.getY();

		if (x > 1 && y > 45 && x < 432 && y < 476){
			
			x = (x-2)/54;
			y = (y-44-2)/54;
			String mvd = "";
			mvd+=(char)(x+97);
			mvd+=(char)(y+49);
			out.println(mvd);
//			serverMessagePane.setText("X: " + x + " Y: " + y);
			updateState();
			repaint();
			try{
				if(in.ready()){
					mvd = in.readLine();
					parseComments(mvd);
					out.println("OINK"); //Throw-away line so server will close the socket...
					socket.close();
				}
			}catch(IOException q){
			//Do nothing
			}

		}
	}


	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}


	
	@Override
	public void keyTyped(KeyEvent e) {
		if (e.getKeyChar() == '\n'){
			comment = ((JTextPane)e.getSource()).getText();
		}
		
	}


	@Override
	public void keyPressed(KeyEvent e) {
		
		
	}


	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	public void updateState(){
		if(valid==false) return;
		try{
		for(int i=0; i<8; i++){
			for(int j=0; j<8; j++){
				positions[j][i] = (char) in.read();
//				System.out.print(positions[j][i]);
			}
//			System.out.print("\n");
		}
		in.readLine();
		}catch(IOException e){
			//Do nothing
		}
	}
	
	public void parseComments(String s){
		int i;
		for(i=0; i< s.length()-1; i++){
			if(s.charAt(i)==';'){
				break;
			}
		}
		commentPane.setText(s.substring(i+1));		
	}
	
}
